package com.lcf.framework.query;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lcf.framework.constant.SysConstant;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * 分页基类
 *
 * @author lcf
 */
@Data
@NoArgsConstructor
public class PageQuery<T> {
    @Schema(description = "页码")
    private Integer pageNum;
    @Schema(description = "每页条数")
    private Integer pageSize;
    @Schema(description = "排序字段，格式如下：userName,createDate")
    private String orderColumn;
    @Schema(description = "排序规则，格式如下：asc,desc")
    private String orderRule;

    public Page<T> toPage() {
        pageNum = pageNum == null ? SysConstant.DEFAULT_PAGE_NUM : pageNum;
        pageSize = pageSize == null ? SysConstant.DEFAULT_PAGE_SIZE : pageSize;

        Page<T> page = new Page<>(pageNum, pageSize);

        return addOrder(page);
    }

    private Page<T> addOrder(Page<T> page) {
        if (StringUtils.isBlank(orderColumn)) {
            return page;
        }

        String[] columnList = StrUtil.splitToArray(orderColumn, ",");
        String[] ruleList = StrUtil.splitToArray(orderRule, ",");
        List<OrderItem> orderItemList = new ArrayList<>();

        for (int i = 0; i < columnList.length; i++) {
            //根据实体类字段名称获取数据库字段名称，实体类若有TableField，则获取TableField注解value值
            String dbFieldName = FieldMapper.getDatabaseFieldName(getEntityClass(), columnList[i]);
            orderItemList.add("asc".equalsIgnoreCase(ruleList[i]) ? OrderItem.asc(dbFieldName) : OrderItem.desc(dbFieldName));
        }

        page.addOrder(orderItemList);

        return page;
    }

    @SuppressWarnings("unchecked")
    private Class<T> getEntityClass() {
        //获取泛型的class类型
        Type genericSuperclass = getClass().getGenericSuperclass();
        ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
        //PageQuery只有一个泛型所以直接获取下标为0的泛型
        return (Class<T>) parameterizedType.getActualTypeArguments()[0];
    }

    ;
}
